package sk.naive.talker.command;

import sk.naive.talker.*;
import sk.naive.talker.message.DefaultMessageFactory;
import sk.naive.talker.props.*;
import sk.naive.talker.persistence.PersistenceException;

import sk.naive.talker.util.Utils;

import java.rmi.RemoteException;
import java.util.regex.*;
import java.util.logging.Level;

/**
 * @author <a href="mailto:rytier@naive.deepblue.sk">Martin "Rytier" Kerni</a>
 * @version $Revision: 1.21 $ $Date: 2005/02/20 13:08:16 $
 */
public class BoardAdmin extends AbstractCommand {
	private static final String CMD_ORDER = "order";
	private static final String CMD_EDITOR = "editor";

	public static final String PERM_BOARD_ADMIN = "boardAdmin";

	public void exec()
		throws CommandException,
		RemoteException {
		Utils.checkPermission(user, PERM_BOARD_ADMIN);

		if (params == null) {
			sendMisusageWarning();
			return;
		}
		Pattern pattern = Pattern.compile("(\\S+) +(\\S+)(?: +(\\S+))?");
		Matcher matcher = pattern.matcher(params);
		if (!matcher.matches()) {
			sendMisusageWarning();
			return;
		}

		BoardFinder bf = commandDispatcher.boardFinder();

		String boardName = matcher.group(1);
		String boardCmd = matcher.group(2).toLowerCase();
		try {
			if (CommandKeywords.CREATE.startsWith(boardCmd)) {
				Board brd = bf.createBoard(boardName);
				if (brd != null) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, brd.getName());
					sendHelper().sendMessage(user, "boardAdmin.created");
					logger().log(Level.INFO, "User {0} created board {1}.", new Object[]{user.getLogin(), brd.getName()});
				} else {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, boardName);
					sendHelper().sendMessage(user, "boardAdmin.alreadyExists");
				}
			} else if (CommandKeywords.RELOAD.startsWith(boardCmd)) {
				Board board = bf.findBoardByName(boardName);
				if (board == null) {
					noSuchBoardWarning(user, boardName);
					return;
				}
				board.init();
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, board.getName());
				sendHelper().sendMessage(user, "boardAdmin.reloadOk");
			} else if (CommandKeywords.REMOVE.startsWith(boardCmd)) {
				Board brd = bf.findBoardByName(boardName);
				if (brd == null) {
					noSuchBoardWarning(user, boardName);
					return;
				}
				bf.destroy(brd);
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, brd.getName());
				sendHelper().sendMessage(user, "boardAdmin.removed");
				logger().log(Level.INFO, "User {0} removed board {1}.", new Object[]{user.getLogin(), brd.getName()});
			} else if (CommandKeywords.RENAME.startsWith(boardCmd)) {
				if (matcher.group(3) == null) {
					sendMisusageWarning();
					return;
				}
				Board brd = bf.findBoardByName(boardName);
				if (brd == null) {
					noSuchBoardWarning(user, boardName);
					return;
				}
				String oldName = brd.getName();
				String newName = Utils.normalize(matcher.group(3));
				bf.rename(brd, newName);
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, oldName);
				ctxSet(DefaultMessageFactory.CTXKEY_VAL + 1, brd.getName());
				sendHelper().sendMessage(user, "boardAdmin.renamed");
				logger().log(Level.INFO, "User {0} renamed board {1} to {2}.", new Object[]{user.getLogin(), oldName, newName});
			} else if (CMD_ORDER.startsWith(boardCmd)) {
				Board board = bf.findBoardByName(boardName);
				if (board == null) {
					noSuchBoardWarning(user, boardName);
					return;
				}
				if (matcher.group(3) == null) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, board.getName());
					ctxSet(DefaultMessageFactory.CTXKEY_VAL + 1, board.getOrder());
					sendHelper().sendMessage(user, "boardAdmin.sortStatus");
					return;
				}
				String value = Utils.findFirstInCollection(matcher.group(3), board.getProperty(Board.BPROP_ORDER).validValues(), true);
				if (value != null) {
					board.set(Board.BPROP_ORDER, value);
					board.init();
				} else {
					sendMisusageWarning();
					return;
				}
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, board.getName());
				ctxSet(DefaultMessageFactory.CTXKEY_VAL + 1, value);
				sendHelper().sendMessage(user, "boardAdmin.sortOk");
			} else if (CMD_EDITOR.startsWith(boardCmd)) {
				Board board = bf.findBoardByName(boardName);
				if (board == null) {
					noSuchBoardWarning(user, boardName);
					return;
				}
				UserFinder uf = commandDispatcher.getUserFinder();
				String editorLogin = matcher.group(3);
				if (editorLogin == null) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, board.getName());
					if (board.getEditors().isEmpty()) {
						sendHelper().sendMessage(user, "boardAdmin.editorStatusEmpty");
					} else {
						StringBuilder sb = new StringBuilder();
						Boolean firstTime = true;
						for (Integer id : board.getEditors()) {
							User editor = uf.findUserById(id);
							if (firstTime) {
								firstTime = false;
							} else {
								sb.append(getString("listDelim", user.getProperties()));
							}
							sb.append(getString("userName", editor.getProperties()));
						}
						ctxSet(DefaultMessageFactory.CTXKEY_VAL + 1, sb.toString());
						sendHelper().sendMessage(user, "boardAdmin.editorStatus");
					}
				} else {
					User editor = uf.findUserByLogin(editorLogin);
					if (editor != null) {
						ctxSet(DefaultMessageFactory.CTXKEY_VAL, board.getName());
						ctxSet(DefaultMessageFactory.CTXKEY_VAL + "Edt", editor.getProperties());
						if (!board.getEditors().isEmpty() && board.isEditor(editor)) {
							board.removeEditor(editor);
							sendHelper().sendMessage(user, "boardAdmin.editorRemove");
						} else {
							board.addEditor(editor);
							sendHelper().sendMessage(user, "boardAdmin.editorAdd");
						}
					} else {
						sendUserNotFoundMessage(editorLogin);
						return;
					}
				}
			} else {
				// TODO show board settings etcetera...
				sendMisusageWarning();
			}
		} catch (PersistenceException e) {
			throw new CommandException(e);
		} catch (PropertyStoreException e) {
			throw new CommandException(e);
		}
	}

	private void noSuchBoardWarning(User u, String roomName) throws RemoteException {
		ctxSet(DefaultMessageFactory.CTXKEY_VAL, roomName);
		sendHelper().sendMessage(u, "boardAdmin.noSuchBoard");
	}
}